package com.shiroha.user.service.impl;

import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.shiroha.common.enums.GroupRole;
import com.shiroha.common.exception.BadRequestException;
import com.shiroha.common.pojo.dto.GroupMemberDTO;
import com.shiroha.user.mapper.GroupMemberMapper;
import com.shiroha.user.pojo.CachedUser;
import com.shiroha.user.pojo.GroupMember;
import com.shiroha.user.service.ICachedUserService;
import com.shiroha.user.service.IGroupMemberService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;

import static com.shiroha.user.pojo.table.Tables.*;
import static com.shiroha.user.pojo.table.Tables.CACHED_USER;

@Service
@AllArgsConstructor
public class GroupMemberServiceImpl extends ServiceImpl<GroupMemberMapper, GroupMember> implements IGroupMemberService {

    private final ICachedUserService cachedUserService;

    /**
     * 获取某个群组中所有成员的基本信息
     *
     * @param userId 访问者ID
     * @param groupId 群组ID
     * @return 成员信息列表
     */
    @Override
    public List<GroupMemberDTO> getAllGroupMembersByGroupId(UUID userId, Long groupId) {
        QueryWrapper queryWrapper = QueryChain.create()
                .select(
                        GROUP_MEMBER.ID,
                        CHAT_GROUP.ID.as("group_id"),
                        GROUP_MEMBER.USER_ID,
                        CACHED_USER.AVATAR,
                        GROUP_MEMBER.NICKNAME,
                        GROUP_MEMBER.ROLE
                )
                .from(CHAT_GROUP)
                .innerJoin(GROUP_MEMBER).on(GROUP_MEMBER.ID.eq(CHAT_GROUP.ID))
                .innerJoin(CACHED_USER).on(CACHED_USER.ID.eq(GROUP_MEMBER.USER_ID));

        return this.listAs(queryWrapper, GroupMemberDTO.class);
    }

    /**
     * 添加用户到群组中
     *
     * @param userId 请求者ID
     * @param groupId 群组ID
     * @param memberId 成员ID
     */
    @Override
    @Transactional
    public boolean addGroupMemberToGroup(UUID userId, Long groupId, UUID memberId) {
        if(userId.equals(memberId)) {
            throw new BadRequestException("不能添加自己到群组中");
        }

        QueryWrapper queryWrapper = QueryChain.create()
                .where(GROUP_MEMBER.USER_ID.eq(userId)
                        .and(GROUP_MEMBER.GROUP_ID.eq(groupId))
                        .and(GROUP_MEMBER.ROLE.eq(GroupRole.GROUP_LEADER))
                        .or(GROUP_MEMBER.ROLE.eq(GroupRole.GROUP_ADMIN)));
        if(!this.exists(queryWrapper)) {
            return false;
        }
        GroupMember groupMember = new GroupMember();
        groupMember.setGroupId(groupId);
        groupMember.setUserId(userId);
        groupMember.setRole(GroupRole.GROUP_MEMBER);
        CachedUser member = cachedUserService.getById(memberId);
        groupMember.setNickname(member.getUsername());
        return this.save(groupMember);
    }

    /**
     * 设置成员为管理员
     *
     * @param userId 请求者ID
     * @param groupId 群组ID
     * @param memberId 成员ID
     */
    @Override
    @Transactional
    public boolean setAdminForGroup(UUID userId, Long groupId, UUID memberId) {
        if(userId.equals(memberId)) {
            throw new BadRequestException("不能设置自己为管理员");
        }

        return this.mapper.setAdminForGroup(userId, groupId, memberId) > 0;
    }

    /**
     * 从群组中删除成员
     *
     * @param userId 访问者ID
     * @param groupId 群组ID
     * @param memberId 成员ID
     */
    @Override
    public boolean deleteGroupMemberFromGroup(UUID userId, Long groupId, UUID memberId) {
        if(userId.equals(memberId)) {
            throw new BadRequestException("不能删除自己");
        }

        return this.mapper.deleteGroupMemberFromGroup(userId, groupId, memberId) > 0;
    }

    /**
     * 用户是否是群组的管理员或群主
     *
     * @param userId  用户ID
     * @param groupId 群组ID
     * @return 是否是群组的管理员或群主
     */
    @Override
    public boolean isAdminForGroup(UUID userId, Long groupId) {
        QueryWrapper queryWrapper = QueryChain.create()
                .where(GROUP_MEMBER.GROUP_ID.eq(groupId))
                .and(GROUP_MEMBER.USER_ID.eq(userId))
                .and((GROUP_MEMBER.ROLE.eq(GroupRole.GROUP_ADMIN)
                        .or(GROUP_MEMBER.ROLE.eq(GroupRole.GROUP_LEADER))));
        return this.exists(queryWrapper);
    }
}
